import numpy as np
import cv2
import pyautogui
import time
import pydirectinput
import sys
import win32gui
import win32con


def detect():
    print("--- Етап 1. Пошук даних")
    start = time.time()
    print(" --- Скріншот")
    image = pyautogui.screenshot()

    img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
    print(" --- Завантаження шаблонів")
    template = cv2.imread('temp.png')
    template2 = cv2.imread('temp2.png')

    locs = []
    print(" --- Пошук квадратів по шаблону")
    while True:
        result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
        _ , max_val, _, max_loc = cv2.minMaxLoc(result)
        if max_val < 0.5:
            break
        locs.append(max_loc)
        x1 = max_loc[0]
        y1 = max_loc[1]

        x2 = x1 + 40
        y2 = y1 + 40
        cv2.rectangle(img, (x1, y1), (x2, y2), (255, 255, 255), -1)
    print(" --- Пошук закінчено")
    loc = min(locs)
    x1 = loc[0]
    y1 = loc[1]

    x2 = x1 + 440
    y2 = y1 + 210

    coo1 = [[x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]]
    cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 1)

    y1 = y2 + 10
    y2 += 220

    cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 1)
    coo2 = [[x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]]

    print(" --- Пошук кнопки відправки по шаблону")
    result = cv2.matchTemplate(img, template2, cv2.TM_CCOEFF_NORMED)
    _, max_val, _, max_loc = cv2.minMaxLoc(result)
    print(" --- Пошук закінчено")
    x1 = max_loc[0] + 20
    y1 = max_loc[1] + 20
    coo3 = [[x1, y1]]
    end = time.time() - start
    print(f"--- Етап 1. Завершено за {end} секунд")
    return coo1, coo2, coo3


def move_and_click(coo, d, no=False):
    for c in coo:
        pydirectinput.moveTo(c[0], c[1])
        pydirectinput.click()
        if no:
            time.sleep(np.random.uniform(*d))


def work(d1, d2):
    start = time.time() 
    coo1, coo2, coo3 = detect()
    start_1 = time.time()
    print("--- Етап 2. Малювання і відправка")
    print(" --- Малювання квадрату 1")
    move_and_click(coo1, d2)
    print(" --- Малювання квадрату 2")
    move_and_click(coo2, d2)
    print(" --- Відправка")
    move_and_click([coo3[0], coo3[0], coo3[0]], d2, True)
    end = time.time() - start
    print(f"--- Етап 2. Завершено за {(time.time() - start_1)} секунд.")
    if end <= 13:
        pause = (13 - end) + np.random.uniform(*d2) + d1
        print(" ---- Етап 1 + Етап 2 виконано менше ніж за 13 секунд.") 
        print(f" ---- Додаткова випадкова пауза {pause} секунд")
        time.sleep(pause)
    


def main(rep, d1, d2):
    print(f"Буде зроблено {rep} повторів")
    print(f"Затримка перед наступним завданням {d1} секунд")
    print(f"Затримка між кліками миші між {d2[0]} і {d2[1]} секунд")
    print("Робота почнеться через 5 секунд. Перемкніться на гру із відкритим"\
        " Діскавері")
    time.sleep(5)
    for _ in range(rep):
        print(f"{''.join([' ' for _ in range(30)])}-- {(_ + 1)} / {rep} --")
        try:
            work(d1, d2)
            time.sleep(d1)
        except ValueError as e:
            print("ОЧІКУВАНА ПОМИЛКА: \n", e)
            print(f"Повторна спроба через {d1} секунд.")
            print("Якщо так і продовжиться збільш затримку між завданнями")
            time.sleep(d1)
            work(d1, d2)


def help_():
    print(f"""
{sys.argv[0]} має такі параметри:
-h,--help        - виклик цієї справки(також буде виведено без аргументів, але 
                     продовжить роботу із параметрами по замовчанню)
-r <ціле число>  - кількість повторів (по замовчанню = 100)
-d1 <ціле число> - затримка перед наступним завданням у секундах
                     (по замовчанню = 2)
-d2 <ціле число/дріб-ціле число/дріб> 
                 - випадкова затримка між кліками миші в секундах
                     (по замовчанню = 0.6-1) 
""")


def args_manager(arg, one=False):
    if arg in sys.argv:
        return True if one else sys.argv[sys.argv.index(arg)+1]
    return False


if __name__ == "__main__":

    print("Вікно командного рядка закріплено поверх інших вікон.")
    hwnd = win32gui.GetForegroundWindow()
    rect = list(win32gui.GetWindowRect(hwnd))
    rect[2] = 700
    rect[3] = 480
    win32gui.SetWindowPos(hwnd,win32con.HWND_TOPMOST, *rect ,0)
    
    am = args_manager

    if len(sys.argv) < 2:
        help_()
    if am("-h", True) or am("--help", True):
        help_()
        exit(0)

    rep = 100
    d1 = 3
    d2 = [0.6, 1]

    try:
        if am("-r"):
            rep = int(am("-r"))
        if am("-d1"):
            d1 = int(am("-d1"))
        if am("-d2"):
            d2_ = am("-d2").split("-")
            d2 = [float(d2_[0]), float(d2_[1])]
    except Exception as e:
        print(f"Щось пішло не так. Помилка:\n{e} ")
        win32gui.SetWindowPos(hwnd,win32con.HWND_NOTOPMOST, *rect ,0)
        print("Вікно командного рядка відкріплено")
        exit(1)
    
    try:
        start = time.time()
        main(rep, d1, d2)
        end = time.time() - start
        print(f"Загальний час виконання {end} секунд ({(end / 60)} хвилин)")
    except ValueError as e:
        print(f"ПОМИЛКА:\n{e} ")
        print("""
Можливо вікно проекту Діскавері щось перекриває. 
Спробуй знову, але так, щоб нічого не перекривало 
кнопку відправки і лівий верхній квадрат із 25 малих 
сірих квадратів.
Або збільш затримку між завданнями
        """)
    except Exception as e:
        print(f"НЕОЧІКУВАНА ПОМИЛКА:\n{e} ")
        exit(1)
    finally:
        win32gui.SetWindowPos(hwnd,win32con.HWND_NOTOPMOST, *rect ,0)
        print("Вікно командного рядка відкріплено")
  